package main

import (
	"fmt"
	"reflect"
)

type Person struct {
	Name string `json:"my_name"`
	Age int `json:"my_age"`
	Sal float64
	Address string
}

func (p Person) Print(){
	fmt.Println(".......Print()......")
	fmt.Println(p.Name)
	fmt.Println("------------------")
}

func (p Person) GetSum(n1 int,n2 int) int {
	return n1+n2
}

func (p Person) ChangeFiled(name string,age int,sal float64,address string) {
	p.Name = name
	p.Age = age
	p.Sal = sal
	p.Address = address
	fmt.Println(p)
}

func testReflect(b interface{})  {
	rTyp := reflect.TypeOf(b)
	fmt.Printf("rTyp = %v\n",rTyp)

	rVal := reflect.ValueOf(b)
	fmt.Printf("rVal = %v\n",rVal)

	kd := rVal.Kind()
	fmt.Printf("kd = %v\n",kd)

	if kd != reflect.Struct {
		fmt.Println("类型错误")
		return
	}

	num := rVal.NumField()
	fmt.Printf("Person的字段有%d个\n",num)

	for i:=0;i<num;i++ {
		fmt.Printf("字段:%d,值为%v\n",i+1,rVal.Field(i))
		//取出tag标签的值
		tagVal := rTyp.Field(i).Tag.Get("json")
		if tagVal != "" {
			fmt.Printf("字段%d,tag为%v\n",i+1,tagVal)
		}
	}

	method := rVal.NumMethod()
	fmt.Printf("Person的方法有%d个\n",method)

	rVal.Method(2).Call(nil)   //按照方法名的ASCII码进行排序

	var params1 []reflect.Value
	params1 = make([]reflect.Value,2)
	params1[0] = reflect.ValueOf(10)
	params1[1] = reflect.ValueOf(20)
	res := rVal.Method(1).Call(params1)
	fmt.Printf("调用方法的结果是%d\n",res[0].Int())

	var params2 = make([]reflect.Value,4)
	params2[0] = reflect.ValueOf("jack")
	params2[1] = reflect.ValueOf(55)
	params2[2] = reflect.ValueOf(90.0)
	params2[3] = reflect.ValueOf("上海")
	rVal.Method(0).Call(params2)

	fmt.Printf("rVal = %v\n",rVal)
}

func main()  {
	p := Person {
		Name : "tom",
		Age : 28,
		Sal : 99999.8,
		Address : "北京",
	}
	testReflect(p)
}
